package commEntity

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Sort"
	"reflect"
	"sync"
)

type factory struct {
	mutex  sync.Mutex
	schema map[string]IEntity
}

func (e *factory) Register(entity IEntity) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	e.schema[entity.Type()] = entity
}

func (e *factory) NewEntity(entityType string) (IEntity, error) {
	e.mutex.Lock()
	defer e.mutex.Unlock()

	entity := e.schema[entityType]
	if entity == nil {
		return nil, errors.New("未定义该Entity：" + entityType)
	}

	return entity.NewEntity(), nil
}

func NewEntity(entityType string) (IEntity, error) {
	return Factory.NewEntity(entityType)
}

func BuildPoList(entityList []IEntity) []map[string]interface{} {
	poList := BuildPoList(entityList)
	jsn := Json.BuildJson(poList)
	return Json.BuildMapListByJson(jsn)
}

func BuildMapList(entityList []IEntity) []map[string]interface{} {
	list := make([]map[string]interface{}, 0)
	for _, entity := range entityList {
		po := entity.BuildToPo()
		mp := Json.BuildMap(po)
		list = append(list, mp)
	}

	return list
}

func GetIDList(entityList []IEntity) []int64 {
	list := make([]int64, 0)
	for _, entity := range entityList {
		list = append(list, entity.GetBaseEntity().Id)
	}

	return list
}

func GetKeyList(entityList []IEntity) []string {
	list := make([]string, 0)
	for _, entity := range entityList {
		list = append(list, entity.MakeServiceKey())
	}

	return list
}

func BuildMap(entity IEntity) map[string]interface{} {
	po := entity.BuildToPo()
	mp := Json.BuildMap(po)
	return mp
}

func BuildEntityByJson(entityType string, jsn *string) (IEntity, error) {
	entity, err := NewEntity(entityType)
	if err != nil {
		return nil, err
	}

	err = entity.BuildByJson(jsn)
	if err != nil {
		return nil, err
	}

	return entity, nil
}

func GetPoReflectType(entityType string) (string, reflect.Type, error) {
	// 分配一个实例
	entity, err := NewEntity(entityType)
	if err != nil {
		return "", nil, err
	}

	// 构造它的PO
	po := entity.BuildToPo()

	return entity.TableName(), reflect.TypeOf(po), nil
}

func SortMapList(mapList []map[string]interface{}) {
	Sort.Sort(mapList, func(entity1, entity2 interface{}) bool {
		id1 := Map.GetInt64(entity1.(map[string]interface{}), "id", 0)
		id2 := Map.GetInt64(entity2.(map[string]interface{}), "id", 0)
		return id2 < id1
	})
}

func SortEntityList(entityList []IEntity) {
	Sort.Sort(entityList, func(entity1, entity2 interface{}) bool {
		return entity2.(IEntity).GetBaseEntity().Id < entity1.(IEntity).GetBaseEntity().Id
	})
}
